home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
9-Digit Zip Code Directory
/
9-Digit Zip Code Directory (American Business Information) (ABIZIP-12).ISO
/
z4src.zip
/
Z4ZXCP.C
< prev
next >
Wrap
C/C++ Source or Header
|
1993-08-13
|
7KB
|
242 lines
//----------------------------------------------------------------------------
// MODULE DESCRIPTION
//
// Module: z4z5cp.c
// Title: ZIP+4 Engine
// Notice: John M. Weeder
// Copyright (c) 1993. All rights reserved.
// This module contains proprietary information and should be
// treated as confidential.
//
//----------------------------------------------------------------------------
// MAINTENANCE HISTORY
//
// $Workfile$
// $Revision$
// $Author$
// $Date$
// $Log$
//
//----------------------------------------------------------------------------
// MODULE NARRATIVE
//
//
// This module contains the compressor for the ZIP4 cross reference file.
//
// The code in this module should be written entirely in C.
// Do not use any C++ constructs.
//
// This module is portable to:
// DOS 3.X+
// MS Windows 3.X+
// OS/2 2.X+
// OS/2 2.0 PM
// SCO UNIX.
//
// The following compilers are supported:
// MSC 6.0A
// MSC/C++ 7.0
// Borland C++ 3.1 for DOS
// Borland C++ 1.0 for OS/2 2.X
// SCO UNIX cc
//
//----------------------------------------------------------------------------
#include <z4.h>
//----------------------------------------------------------------------------
// Prototypes
//----------------------------------------------------------------------------
static BOOL FN_L Z4ZXCompressAppend(PDATACOMP, PZ4_ZX);
static ULONG ulZipPrev;
static RECID recid;
//----------------------------------------------------------------------------
// Description: Compression function
// Parameters: pdatacomp Compressor data
// Returns: Compression function result code. See data.h.
//----------------------------------------------------------------------------
SHORT FN_E Z4ZXCompress(PDATACOMP pdatacomp)
{
static Z4_ZX zx;
static SIZET cMaxRecords;
static BOOL fPending; // ZIP5 record pending?
static SIZET cZip;
static SIZET cAddonLo;
static SIZET cAddonHi;
LONG lRec = pdatacomp->dlmrec.lId;
PPSZ ppsz = pdatacomp->dlmrec.apsz;
CHAR szAddonLo[MAX_ADDON+1];
CHAR szAddonHi[MAX_ADDON+1];
CHAR szZip5[MAX_ZIP5+1];
CHAR szZip4[MAX_ZIP4+1];
switch (lRec)
{
case DAI_INITIALIZE: // Initialize at startup
cMaxRecords = 0;
Assert(MAX_ZIP4_RECS <= pdatacomp->cbMax / sizeof(RECID));
cZip = DataField(pdatacomp->dlmrec.pcfg, "zipcode");
cAddonLo = DataField(pdatacomp->dlmrec.pcfg, "addon_lo");
cAddonHi = DataField(pdatacomp->dlmrec.pcfg, "addon_hi");
case DAI_START_BLK: // Start block
ulZipPrev = 0L;
fPending = FALSE;
recid.usOffset = 0;
recid.lBlock = 0;
return DAO_SUCCESS;
case DAI_TERMINATE: // Terminate
Output("\nMaximum of %u records in a ZIP+4.\n", cMaxRecords);
case DAI_FAILURE: // Failed
case DAI_END_BLK: // End block
return DAO_SUCCESS;
case DAI_LAST_REC: // This should not happen
if (!fPending)
return DAO_FAILURE;
Z4ZXCompressAppend(pdatacomp, &zx);
return DAO_FLUSH;
}
// Decode
strb2a((PBYTE)ppsz[cAddonLo], MAX_ADDON_BCD, szAddonLo, MAX_ADDON, TRUE);
strb2a((PBYTE)ppsz[cAddonHi], MAX_ADDON_BCD, szAddonHi, MAX_ADDON, TRUE);
strb2a((PBYTE)ppsz[cZip], MAX_ZIP5_BCD, szZip5, MAX_ZIP5, TRUE);
szAddonLo[MAX_ADDON] = '\0';
szAddonHi[MAX_ADDON] = '\0';
szZip5[MAX_ZIP5] = '\0';
strcpy(szZip4, szZip5); // Build +4 code
strcat(szZip4, szAddonLo);
if (fPending)
{
if (strcmp(zx.szZip5, szZip5) != 0
|| strcmp(zx.szAddonLo, szAddonLo) != 0)
{
Z4ZXCompressAppend(pdatacomp, &zx);
fPending = FALSE;
return DAO_MARK_FLUSH;
}
Assert(zx.cRecords < MAX_ZIP4_RECS);
if (strcmp(zx.szAddonHi, szAddonHi) < 0)
strcpy(zx.szAddonHi, szAddonHi);
zx.arecid[zx.cRecords] = pdatacomp->dlmrec.recid;;
zx.cRecords++;
cMaxRecords = MAX(cMaxRecords, zx.cRecords);
return DAO_NEXT;
}
fPending = TRUE;
memset(&zx, 0, sizeof(zx));
strcpy(zx.szAddonLo, szAddonLo);
strcpy(zx.szAddonHi, szAddonHi);
strcpy(zx.szZip5, szZip5);
zx.arecid[zx.cRecords] = pdatacomp->dlmrec.recid;;
zx.cRecords++;
cMaxRecords = MAX(cMaxRecords, zx.cRecords);
return DAO_NEXT;
}
//----------------------------------------------------------------------------
// Description: Compress the current ZIP5 record
// Parameters: pdatacomp Compresser data
// pz5 ZIP5 record
// Returns: TRUE if successful.
//----------------------------------------------------------------------------
static BOOL FN_L Z4ZXCompressAppend(PDATACOMP pdatacomp, PZ4_ZX pzx)
{
ULONG ulDelta, ulZip;
BYTE bBuf[sizeof(RECID) * MAX_ZIP4_RECS];
SIZET cBuf;
PBYTE pb = pdatacomp->pb;
CHAR szZip4[MAX_ZIP4+1];
USHORT usAddonLo, usAddonHi, usDelta;
strcpy(szZip4, pzx->szZip5); // Build +4 code
strcat(szZip4, pzx->szAddonLo);
ulZip = (ULONG)atol(szZip4); // Compute ZIP4 as ulong
ulDelta = ulZip - ulZipPrev; // Compute delta from previous
if (ulZip <= ulZipPrev)
Output("\nZIP+4: %09lu %09lu\n", ulZip, ulZipPrev);
Assert(ulZip > ulZipPrev);
usAddonLo = (USHORT)atoi(pzx->szAddonLo);
usAddonHi = (USHORT)atoi(pzx->szAddonHi);
Assert(usAddonHi >= usAddonLo);
usDelta = usAddonHi - usAddonLo;
*pb = (BYTE)(ulDelta & 0x0000003FL);
if (usDelta)
*pb |= 0x40; // Range follows!
if (ulDelta > 63 || ulDelta == 0) // First byte can not be 0!!
{
*pb |= 0x80;
pb++;
ulDelta >>= 6;
Assert((ulDelta & 0xFF000000L) == 0);
*pb++ = (BYTE)(ulDelta & 0x000000FFL);
ulDelta >>= 8;
*pb++ = (BYTE)(ulDelta & 0x000000FFL);
ulDelta >>= 8;
*pb++ = (BYTE)(ulDelta & 0x000000FFL);
}
else
pb++;
if (usDelta) // Encode range delta
{
usDelta--;
*pb = (BYTE)(usDelta & 0x007F);
if (usDelta > 0x007F)
{
*pb |= 0x80;
pb++;
Assert((usDelta >> 7) < 256);
*pb = (BYTE)usDelta;
pb++;
}
else
pb++;
}
// Encode record ids
if (!RecIdEncode(pzx->arecid, pzx->cRecords, bBuf, sizeof(bBuf), &cBuf, &recid))
return FALSE;
Assert(cBuf); // Encode byte count
cBuf--;
*pb = (BYTE)(cBuf & 0x007F);
if (cBuf > 0x007F)
{
*pb |= 0x80;
pb++;
Assert((cBuf >> 7) < 256);
*pb = (BYTE)cBuf;
pb++;
}
else
pb++;
cBuf++;
Assert(pdatacomp->cb <= pdatacomp->cbMax);
Assert(cBuf + 10 < pdatacomp->cbMax - pdatacomp->cb);
memcpy(pb, bBuf, cBuf); // Copy encoded record ids to output
pb += cBuf;
ulZipPrev = ulZip;
pdatacomp->cb = (SIZET)(pb - pdatacomp->pb);
return TRUE;
}
//----------------------------------------------------------------------------
//------------------------------- End of File --------------------------------
//----------------------------------------------------------------------------